package com.wondream.myframework.app.common.apollo;

import com.ctrip.framework.apollo.build.ApolloInjector;
import com.ctrip.framework.apollo.util.ConfigUtil;
import com.google.common.base.Splitter;
import javafx.util.Pair;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Iterator;

@Data
@NoArgsConstructor
public class CfssConfigProcessor implements BeanPostProcessor, EnvironmentAware {

    private final String separatorPattern = ",|;\\|";

    private final String pathEnv = "cfss.configProperties.path";

    private Environment environment;

    @Resource
    private ConfigurationPropertiesBindingPostProcessor configurationPropertiesBindingPostProcessor;

    private final ConfigUtil configUtil = (ConfigUtil) ApolloInjector.getInstance(ConfigUtil.class);

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (!this.configUtil.isAutoUpdateInjectedSpringPropertiesEnabled()) {
            return bean;
        } else {
            String paths = this.environment.getProperty("cfss.configProperties.path");
            if (!StringUtils.hasLength(paths)) {
                return bean;
            } else {
                Iterable<String> pathIte = Splitter.onPattern(separatorPattern).split(paths);
                if (!this.effectPath(pathIte, bean.getClass().getName())) {
                    return bean;
                } else {
                    ConfigurationProperties annotation = AnnotationUtils.findAnnotation(bean.getClass(), ConfigurationProperties.class);
                    if (null != annotation) {
                        String prefix = annotation.prefix();
                        CfssSpringBootConfigRegistry.register(prefix, new Pair(beanName, bean), this.configurationPropertiesBindingPostProcessor);
                    }
                    return bean;
                }
            }
        }
    }

    private boolean effectPath(Iterable<String> paths, String matchPath) {
        Iterator var3 = paths.iterator();
        String path;
        do {
            if (!var3.hasNext()) {
                return false;
            }
            path = (String) var3.next();
        } while (matchPath.indexOf(path) != 0);
        return true;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}
